#ifndef __PLUGIN_PICTURE_H__
#define __PLUGIN_PICTURE_H__
#include "t2mpgdec.h"

#ifdef WIN32
#define V_KEY_PLAY      0
#define V_KEY_PAUSE     1
#define V_KEY_FF    2
#define V_KEY_FB    3
#define V_KEY_SLOW    4
#define V_KEY_STOP      5
#define V_KEY_SEEK        6
#define V_KEY_CHGAUD    7
#endif

//Error code definition

/*General PE errors*/
#define AF_ERR_PE_OK                    0
#define AF_ERR_NOT_AVAILABLE            0xffffffff
#define AF_ERR_PE_FAIL                  0xfffffffe

/*PE message errors*/
#define AF_ERR_PE_MSG                   1
#define AF_ERR_PE_MSG_OVERFLOW          (AF_ERR_PE_MSG)
#define AF_ERR_PE_MSG_TYPE              (AF_ERR_PE_MSG+1)
#define AF_ERR_PE_MSG_HANDLE            (AF_ERR_PE_MSG+2)
#define AF_ERR_PE_MSG_STREAMTYPE        (AF_ERR_PE_MSG+3)
#define AF_ERR_PE_MSG_DECODERTHREAD     (AF_ERR_PE_MSG+4)
#define AF_ERR_PE_MSG_PLAYSPEED         (AF_ERR_PE_MSG+5)
#define AF_ERR_PE_MSG_END               (AF_ERR_PE_MSG_PLAYSPEED)

/*PE decoder errors*/
#define AF_ERR_PE_DEC                   (AF_ERR_PE_MSG_END)      
#define AF_ERR_PE_DEC_NULL_INITFUNC     (AF_ERR_PE_DEC+1)
#define AF_ERR_PE_DEC_NULL_DECFUNC      (AF_ERR_PE_DEC+2)
#define AF_ERR_PE_DEC_NULL_GETCAPFUNC   (AF_ERR_PE_DEC+3)
#define AF_ERR_PE_DEC_ILLEGAL_DECTHREAD (AF_ERR_PE_DEC+4)
#define AF_ERR_PE_DEC_END               (AF_ERR_PE_DEC_ILLEGAL_DECTHREAD)

/*PE callback function errors*/
#define AF_ERR_PE_CB                    (AF_ERR_PE_DEC_END)
#define AF_ERR_PE_CB_NULL_READ          (AF_ERR_PE_CB+1)
#define AF_ERR_PE_CB_NULL_INITDECBUF    (AF_ERR_PE_CB+2)
#define AF_ERR_PE_CB_NULL_RELEASEDECBUF (AF_ERR_PE_CB+3)

//Constant definition
/*Message types*/
#define AF_C_PEMSG_STREAM_START 0
#define AF_C_PEMSG_PLAY 1
#define AF_C_PEMSG_FF 2
#define AF_C_PEMSG_FR 3
#define AF_C_PEMSG_SLOW 4
#define AF_C_PEMSG_PAUSE 5
#define AF_C_PEMSG_STEP 6
#define AF_C_PEMSG_STOP 7
#define AF_C_PEMSG_SEEK 8
#define AF_C_PEMSG_CHANGE_VID 9
#define AF_C_PEMSG_CHANGE_AID 10
#define AF_C_PEMSG_CHANGE_SID 11
#define AF_C_PEMSG_RESET_PLAYPOINT 12
#define AF_C_PEMSG_MAX 12

#define AF_C_MAXOP		9

/* return value for video container init and decode:
   See pfn_decoder_init and pfn_decoder_run
*/
#define VIDEO_CON_FILE_PLAY_FAILED  FALSE   // corrupt file
#define VIDEO_CON_FILE_PLAY_OK      TRUE    // file play OK
#define VIDEO_CON_FILE_UNKNOWN      2       // file type unknown


/*Container IO Control Command*/
#define CONTAINER_IO_CONTROL_BASE 				0xffff
#define CONTAINER_IO_CONTROL_GET_TIME_MS		(CONTAINER_IO_CONTROL_BASE+1)
#define CONTAINER_IO_CONTROL_EN_AC3_BS_MODE     (CONTAINER_IO_CONTROL_BASE+2)
#define CONTAINER_IO_CONTROL_GET_CHAPTER_INFO   (CONTAINER_IO_CONTROL_BASE+3)
#define CONTAINER_IO_CONTROL_GET_TOTALTIME_MS   (CONTAINER_IO_CONTROL_BASE+4)
#define CONTAINER_IO_CONTROL_SET_AVSYNC_DELAY   (CONTAINER_IO_CONTROL_BASE+5)
#define CONTAINER_IO_CONTROL_EN_MUTE_FIRST		(CONTAINER_IO_CONTROL_BASE+6)

/*Structure definition*/
typedef BOOL (*PAF_PE_Function)(t2DecoderControl *pDecoderCtrl, int PlaySpeed, DWORD SearchTime);
typedef PAF_PE_Function AF_PE_FunctionTable[AF_C_MAXOP][AF_C_MAXOP];
typedef AF_PE_FunctionTable *PAF_PE_FunctionTable;

typedef enum 
{
  PEStop      = 0,
  PEPlay      = 1,
  PEPauseStep = 2,
  PEFFx2      = 3,
  PEFFx4      = 4,
  PEFFx8x16x32 = 5,
  PESlow      = 6,
  PERev       = 7,
  PEResumeStop = 8
}AF_PE_PLAY_STATE, *PAF_PE_PLAY_STATE;

typedef enum
{
    AF_E_SEARCH_LAST_KEYFRAME =0,
    AF_E_SEARCH_NEXT_KEYFRAME
}AF_PE_SEARCH_DIR, *PAF_PE_SEARCH_DIR;

typedef struct _AF_PE_MESSAGE
{
    DWORD MsgType; //Message type
    DWORD Handle; //File handle or stream handle, this handle is only available in message"AF_C_PEMSG_STREAM_START"
    DWORD SearchTime; //The seek point. If not seeking operation, this should be INVALID_TIME 
	DWORD ID; //This ID is used to identify the file/stream sent by application. PE will not use this ID, but PE will send this ID back to UI, this ID is only available in message"AF_C_PEMSG_STREAM_START"
    BYTE StreamType; //Stream type
    BOOL EnableBERead; //Enable back end reading for the decoder thread. You can only enable back end reading in message "AF_C_PEMSG_STREAM_START"
    int PlaySpeed; //Play speed. 0: normal spped, 1: 2X speed, 2: 4X speed, 3: 8X speed, 4: 16X speed, 5: 32X speed.
    AF_PE_SEARCH_DIR SearchDir; 
    WORD video_stream_id; //video stream ID to be decoded
	WORD audio_stream_id; //audiostream ID to be decoded
	WORD subp_stream_id; //SP stream ID to be decoded
	DEC_PLAYPOINT_INFO StartPoint;
    DEC_PLAYPOINT_INFO EndPoint;
}AF_PE_MESSAGE, *PAF_PE_MESSAGE;

typedef struct _AF_PE_DECODER
{
	BYTE StreamType;
    BOOL (*DecoderInit)(DEC_INIT_PAR DecInitPar); 
	BOOL (*DecoderSelector)(t2DecoderBuffer *pDecoderBuffer); 
	BOOL (*DecoderReset)(); 
	BOOL (*DecoderGetCap)(t2DecoderCap *pDecoderCap);
    BOOL (*DecoderSetPlayPoint)(DEC_PLAYPOINT_INFO StartPoint, DEC_PLAYPOINT_INFO EndPoint);
    DWORD (*DecoderGetLastErrMsg)(); 
    DWORD (*DecoderGetPlayTime)();
    DWORD (*DecoderGetFrameNumber)();
    DWORD (*DecoderGetStreamInfo)(PDEC_STREAM_INFO pStreamInfo);
    void (*DecoderExtraStartCB)();
    void (*DecoderExtraExitCB)();
    DWORD (*DecoderGetPlayPoint)(PDEC_PLAYPOINT_INFO pPlayPoint);
    DWORD (*DecoderSetOutputWin)(PDEC_OUTPUT_WIN OutputWin);
    PAF_PE_FunctionTable pDecFuncTable; //decoder control services functions provided by decoder control library
} AF_PE_DECODER, *PAF_PE_DECODER;

typedef struct _AF_PE_CALLBACK
{
    DWORD (*DecoderReadData)(DWORD Handle, BYTE *buf, DWORD size);
    BOOL (*DecoderSeekData)(DWORD Handle, INT64 offset, DWORD origin);
    DWORD (*DecoderTellPos)(DWORD Handle);
    DWORD (*InitDecoderBuffer)(t2DecoderCap *PDecoderCap, BYTE StreamType, t2FrameBuffer *FrameBuffer, t2DecOtherBuf *otherBuffer);
    DWORD (*ReleaseDecoderBuffer)(BYTE StreamType);
}AF_PE_CALLBACK, *PAF_PE_CALLBACK;

//add by mark
typedef struct
{
    UINT32 buffer_addr;
    UINT32 buffer_size;
} PE_CACHE_BUFFER;
//end

// video(container) plugin interface

#ifndef WIN32
typedef struct
{
    struct MPSource_CallBack    VideoMPCallBack;
    struct PIPSource_CallBack   VideoPIPCallBack;
} VE_DE_CALLBACK;
#else
typedef struct
{
	void *mp_callback;
	void *pip_callback;
} VE_DE_CALLBACK;
#endif

typedef int (*pfn_is_our_file) (char *filename);	/* Return 1 if the plugin can handle the file */
typedef BOOL (*pfn_decoder_init)(DEC_INIT_PAR DecInitPar); //Decoder init function
typedef BOOL (*pfn_decoder_run)(mp_callback_func cb); //Decoder decodes main function
typedef BOOL (*pfn_dedoder_reset)(); //Decoder resets function
typedef DWORD (*pfn_get_last_error)(); //Get last decoder error message code
typedef int (*pfn_decoder_get_param)(const struct pe_video_cfg *pvideo_config, DEC_INIT_PAR *pInitParam, VE_DE_CALLBACK *pDECallback, void *pOtherParam); // return 1(success)
typedef int (*pfn_decoder_rls_param)(const struct pe_video_cfg *pvideo_config, DEC_INIT_PAR *pInitParam, VE_DE_CALLBACK *pDECallback, void *pOtherParam); // return 1(success)
typedef int (*pfn_get_play_time)(void); // in second
typedef int (*pfn_get_play_time_ms)(void); // in second
typedef int (*pfn_get_stream_info)(PDEC_STREAM_INFO pDecStreamInfo); // return 0 success, otherwise failed
typedef int (*pfn_decoder_ioctl)(unsigned long io_cmd, unsigned long param1, unsigned long param2); // return 0 success, otherwise failed

typedef struct
{
    const char              *name;      // The name of the decoder
    pfn_decoder_init        DecoderInit;
    pfn_decoder_run         DecoderSelector;
    pfn_dedoder_reset       DecoderReset;
    pfn_get_last_error      DecoderGetLastErrMsg;
    pfn_is_our_file         is_our_file;
    pfn_decoder_get_param   get_init_param;
    pfn_decoder_rls_param   rls_init_param;
    pfn_get_play_time       get_play_time;
    pfn_get_stream_info     get_stream_info;
    pfn_decoder_ioctl       decoder_ioctl;
} VIDEO_DECODER;

typedef struct
{
    VIDEO_DECODER           *pdecoder;
    AF_PE_FunctionTable     *pctrl_cmd;
} VIDEO_INPUT_PLUGIN;

#ifndef WIN32
    #define _Video_InputPlugin(x) const VIDEO_INPUT_PLUGIN x __attribute__ ((section(".video.plugin")))
#else
    #define _Video_InputPlugin(x) VIDEO_INPUT_PLUGIN x
#endif

// get file ext name, in lower case, return the length of the file ext name
int get_file_name_ext(const char *filename, char *pext, int ext_size);

//Function prototype
/*-------------------------------------------------------------------
Name: 
    AF_PEInit
Description: 
    Init PE task of application framework, this function should 
    only be called once at the initialization stage
Parameters: 
    [IN]
    [OUT]
Return: 
    AF_ERR_PE_OK: PE task initialization ok
    AF_ERR_PE_FAIL: PE task initialization failed
-------------------------------------------------------------------*/
DWORD AF_PEInit(void);

/*-------------------------------------------------------------------
Name: 
    AF_PESetBEBuf
Description: 
    Set backend reading thread buffer. This function can be called when
    PE is stop to change backend ring buffer address and size.
Parameters: 
    [IN]
        buf:backend reading thread buffer base address
        size:backend reading thread buffer size
        DecoderThread: Indicates which decoder thread will use this buffer
    [OUT]
Return: 
    AF_ERR_PE_OK:  Setting backend reading thread buffer is OK
    AF_ERR_PE_FAIL: Setting backend reading thread buffer is failed 
-------------------------------------------------------------------*/
DWORD AF_PESetBEBuf(BYTE *buf, DWORD size, BYTE DecoderThread);

/*-------------------------------------------------------------------
Name: 
    AF_PERegDecoder
Description: 
    Application call this function to register decoder into PE.
Parameters: 
    [IN]
        DecoderThread: The thread(0, 1) will run the decoder
        Decoder: The decoder to be registered into PE
        PECallback: The callback function of the decoder
        
    [OUT]
Return: 
    AF_ERR_PE_OK: Decoder is registered successfully
    AF_ERR_PE_DEC_NULL_INITFUNC: decoder init function is NULL
    AF_ERR_PE_DEC_NULL_DECFUNC: decoder function is NULL
    AF_ERR_PE_DEC_NULL_GETCAPFUNC: GetCap function is NULL
    AF_ERR_PE_DEC_ILLEGAL_DECTHREAD: illegal decoder thread
    
    AF_ERR_PE_CB_NULL_READ: register null read callback function
    AF_ERR_PE_CB_NULL_INITDECBUF: register null init decoder buffer function
-------------------------------------------------------------------*/
DWORD AF_PERegDecoder(BYTE DecoderThread, AF_PE_DECODER Decoder, AF_PE_CALLBACK PECallback);

/*-------------------------------------------------------------------
Name: 
    AF_PEMessage
Description: 
    Application calls this function in UI to send message to PE to 
    control the playback.
Parameters: 
    [IN]
        DecoderThread: Choose the decoder thread to send the message
        Message: The message to be send to PE
    [OUT]
Return: 
    AF_ERR_PE_OK: if message is sent ok.
    AF_ERR_NOT_AVAILABLE: This message is not available for the decoder
    AF_ERR_PE_MSG_OVERFLOW: message buffer overflow
    AF_ERR_PE_MSG_TYPE: unknown message type
    AF_ERR_PE_MSG_HANDLE: Null stream/file handle
    AF_ERR_PE_MSG_STREAMTYPE: incorrect stream type
    AF_ERR_PE_MSG_DECODERTHREAD: illegal decoder thread number
    AF_ERR_PE_MSG_PLAYSPEED: illegal play speed
-------------------------------------------------------------------*/
DWORD AF_PEMessage(BYTE DecoderThread, AF_PE_MESSAGE Message);

/*-------------------------------------------------------------------
Name: 
    AF_PEGetPlayTime
Description: 
    Application calls this function to get current play time in second.
Parameters: 
    [IN]
        DecoderThread: Choose the decoder thread to get the play time
    [OUT]
Return: 
    AF_ERR_NOT_AVAILABLE: Current decoder can't return current play time, 
    otherwise, current play time in second.
-------------------------------------------------------------------*/
DWORD AF_PEGetPlayTime(BYTE DecoderThread);

/*-------------------------------------------------------------------
Name: 
    AF_PEGetFrameNumber
Description: 
    Application calls this function to get current frame number
Parameters: 
    [IN]
        DecoderThread: Choose the decoder thread to get the play 
        frame number
    [OUT]
Return: 
    AF_ERR_NOT_AVAILABLE: Current decoder cant return current play frame number,
    otherwise, current play frame number.
-------------------------------------------------------------------*/
DWORD AF_PEGetFrameNumber(BYTE DecoderThread);

/*-------------------------------------------------------------------
Name: 
    AF_PEGetStreamInfo
Description: 
    Application calls this function to get stream information
Parameters: 
    [IN]
        DecoderThread: Choose the decoder thread to get the stream information 
        StreamInfo: the pointer to the stream information
    [OUT]
Return: 
    AF_ERR_NOT_AVAILABLE: Current decoder cant return stream infomation            
    AF_ERR_PE_OK: Current decoder can return stream information                     
-------------------------------------------------------------------*/
DWORD AF_PEGetStreamInfo(BYTE DecoderThread, PDEC_STREAM_INFO pStreamInfo);

/*-------------------------------------------------------------------
Name: 
    AF_PEGetPlyState
Description: 
    Application calls this function to get current PE play state.
Parameters: 
    [IN]
        DecoderThread: Choose the decoder thread to get play state
    [OUT]
Return: 
    Current PE play state
-------------------------------------------------------------------*/
AF_PE_PLAY_STATE AF_PEGetPlyState(BYTE DecoderThread);

/*-------------------------------------------------------------------
Name: AF_PEGetPlayPoint
Description: 
    Application calls this function to get current play point information
Parameters: 
    DecoderThread: Choose the decoder thread to get play state
    pPlayPoint: play point information
Return: 
    AF_ERR_NOT_AVAILABLE: Current decoder cant return stream infomation            
    AF_ERR_PE_OK: Current decoder can return stream information                     
-------------------------------------------------------------------*/
DWORD AF_PEGetPlayPoint(BYTE DecoderThread, PDEC_PLAYPOINT_INFO pPlayPoint);

/*-------------------------------------------------------------------
Name: AF_PE_WaitRingBufTaskIdle
Description: 
    Wait ring buffer task idle
Parameters: 
    
Return: 
    
-------------------------------------------------------------------*/
void AF_PE_WaitRingBufTaskIdle(void);
#endif// __PLUGIN_PICTURE_H__


